package org.example.mynote.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.Map;

@Component
public class JwtUtil {
    // 1. 设置一个密钥，不能太简单，实际项目中应该更复杂并放在配置文件中
    private final String secret = "my-super-secret-key-for-note-taking-app-project";
    private final Key key = Keys.hmacShaKeyFor(secret.getBytes());

    // 2. 设置 Token 过期时间，例如 7 天
    private final long expiration = 1000 * 60 * 60 * 24 * 7;

    // 3. 生成 Token 的方法
    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username) // 将用户名作为主题
                .setIssuedAt(new Date(System.currentTimeMillis())) // 设置签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration)) // 设置过期时间
                .signWith(key, SignatureAlgorithm.HS256) // 使用 HS256 算法和密钥签名
                .compact();
    }

    // 4. 从 Token 中解析出用户名的核心逻辑
    private Claims getClaimsFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 5. 从 Token 中获取用户名
    public String getUsernameFromToken(String token) {
        return getClaimsFromToken(token).getSubject();
    }

    // 6. 验证 Token 是否过期
    public boolean isTokenExpired(String token) {
        return getClaimsFromToken(token).getExpiration().before(new Date());
    }

    // 7. 验证 Token 是否有效 (用户名存在且未过期)
    public boolean validateToken(String token, String username) {
        final String usernameFromToken = getUsernameFromToken(token);
        return (username.equals(usernameFromToken) && !isTokenExpired(token));
    }

}
